(function($) {
	
var extra = $.browser.msie ? 0 : 2;

$.fn.autoresize = function(options) {
		
	var settings = $.extend({
		animate: true,
		duration: 100
	},options);

	return this.each(function() {
		var ta = $(this), df = $('<textarea></textarea>');
		ta.addClass('f-autoresize').css({
			resize: 'none',
			outline: 'none',
			overflowY: 'hidden'
		});
		df.width(ta.width());
		df.text(ta.val());
		var styles = {};
		if (window.getComputedStyle) {
			var cs = window.getComputedStyle(this);
			for (var i = 0, maxi = cs.length; i < maxi; i++) {
				var key = cs[i];
				if (key.match(/font|line-?height|text|word|letter|padding|color/i))
					styles[key] = cs.getPropertyValue(key);
			}
		} else if (this.currentStyle) {
			for (var key in this.currentStyle) {
				if (key.match(/font|line-?height|text|word|letter|padding/i))
					styles[key] = this.currentStyle.getAttribute(key);
			}
		}
		df.css($.extend(styles,{ 
			position: 'absolute', 
			left: -2000, 
			top: -2000,
			height: '1em',
			overflow: 'hidden',
			resize: 'none'
		}));
		$('body').append(df);
		var t = null, dh = 0, animate = false, fnt = function() {
			df.val(ta.val() + '\n');
			var dfh = df[0].scrollHeight + extra;
			if (animate) {
				if (dh != dfh) {
					dh = dfh;
					ta.stop().animate({ height: dh },settings.duration);
				}
			} else ta.height(dfh);
			t = null;
		}, fn = function() {
			if (t) clearTimeout(t);
			t = setTimeout(fnt,1);
		};
		ta.keydown(fn).mousedown(fn).mouseup(fn).focus(fn).change(fn);
		fnt();
		animate = settings.animate;
	});

};

$('.f-autoresize').autoresize();

})(jQuery);
